#include "../../common/utility.h"
int is_arp_pck( const uint8_t *pck);
int sip_eq_arpsip(const uint8_t * sip,const uint8_t * arp_pck);
int is_response_arp(char * buf);
int main()
{

    char tap_name[] = "tap1";
    int fd = open_tap(tap_name);
    if (fd == -1)
    {
        ERR("can not open tap name %s", tap_name);
        perror(strerror(errno));
        exit(errno);
    }
    int flags = fcntl(fd, F_GETFL, 0);
    if (flags == -1)
    {
        ERR("get tap fd sys flags err %s %d", strerror(errno), errno);
        exit(errno);
    };
    int err = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
    if (err == -1)
    {
        ERR("set tap fd nonblock flags err %s %d", strerror(errno), errno);
        exit(errno);
    }
    uint8_t sender_hw_address[] = {0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f};
    uint8_t sender_protocl_address[] = {192, 168, 2, 252};
    uint8_t target_hw_address[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
    uint8_t target_protocl_address[] = {192, 168, 2, 1};
    while (1)
    {
        sleep(2);
        struct arp_pck req_arp = arp_maker(sender_hw_address, sender_protocl_address, target_hw_address, target_protocl_address);
        int err = __write_all(fd, &req_arp, sizeof(struct arp_pck));
        if (err < sizeof(struct arp_pck))
        {
            WARN("write all pck failed err code %d", err);
            perror(strerror(errno));
        }
        uint8_t buf[1500] = {0};
        int read_count = read(fd, buf, sizeof(buf));
        if (read_count < 0)
        {
            WARN("read fd warning %s %d", strerror(errno), errno);
            continue;
        }
        LOG("read count %d", read_count);
        if(!is_arp_pck(buf)){
            WARN("pck is not arp pck")
            continue;
        }
        if (!sip_eq_arpsip(target_protocl_address,buf))
        {
            WARN("arp pck is not from target sip");
            continue;
        };
        if (!is_response_arp(buf)){
            WARN("arp pck is not response type");
            continue;
        }
        LOG("find response arp pck");
        struct arp_pck *response = safe_buf_trans_to_type(buf,struct arp_pck,read_count);
        print_arr(response->arp.arp_sha,6,'x');
        free(response);
    }
}

int is_arp_pck(const uint8_t *pck)
{
    if (pck[12] == 0x08 && pck[13] == 0x06)
    {
        LOG("pck is arp pck 0x%02x%02x", pck[12], pck[13]);
        return 1;
    }
    return 0;
}

int sip_eq_arpsip(const uint8_t * sip,const uint8_t * arp_pck){
    LOG("arp pck source ip is %d.%d.%d.%d",
        arp_pck[28],arp_pck[29],arp_pck[30],arp_pck[31]);
    return memcmp(sip,&arp_pck[28],4)==0;
}

int is_response_arp(char * buf){
    return buf[21]==0x02;
    
}
